template<typename T>
class TListItem : public TObject
{
protected:
    T mCurr;
    ref<TListItem<T> > mNext;
public:
    inline TListItem(T curr) : TObject(), mCurr(curr)
    {}

    inline ref<TListItem<T> >& Next()
    {
        return mNext;
    }

    inline T& GetObject()
    {
        return mCurr;
    }
};

template<class T, class Item = TListItem<T> >
class TList : public TArray<ref<Item> >
{
    typedef TArray<ref<Item> > Base;
public:
    typedef ref<Item> ListItem;
    typedef ref<const Item> ConstListItem;
protected:
    ListItem mFirst;
    ListItem mLast;
protected:
    inline ListItem & MakeItem(T & inst)
    {
        return Base::Add(new typename ListItem::Create(inst));
    }
    inline T & Insert(ListItem& prev, T& obj)
    {
        ListItem& newItem = MakeItem(obj);
        newItem->Next() = prev->Next();
        prev->Next() = newItem;
        return obj;
    }
public:
    typedef T	TypeReference;
    typedef Item	TypeItem;
private:
    void Dispose(void)
    {
        mFirst = NullPtr;
        mLast = NullPtr;
    }
public:
    inline TList(void) : Base()
    {}
    virtual ~TList(void)
    {
        Dispose();
    }
public:
    inline ListItem Add(ListItem inst)
    {
        if(Base::Length() == 0)
        {
            return mFirst = mLast = inst;
        }
        else
        {
            return mLast = mLast->Next() = inst;
        }
    }
    //
    inline T Add(T inst)
    {
        if(Base::Length() == 0)
        {
            mFirst = mLast = MakeItem(inst);
        }
        else
        {
            mLast = mLast->Next() = MakeItem(inst);
        }
        return inst;
    }
    //
    inline virtual void Clear(void)
    {
        Dispose();
        Base::Clear();
    }

    inline virtual uint	SetLength(unsigned int dSize)
    {
        //NOTE: alloc maybe call clear for realloc array item, need save first and last item for restore after alloc:)
        //saved it
        ListItem f = mFirst, l = mLast;
        //alloc?
        uint retval = Base::SetLength(dSize);
        //restore
        mFirst = f;
        mLast = l;
        return retval;
    }
    //
    inline ListItem GetItem(uint index)
    {
        return Base::Get(index);
    }

public://Iterator impl
    /*-------------------------------------------------------------------------
 | Iterator:
 | ------------
 | Helper for enumerable class
 ---------------------------------------------------------------------------*/
    class Iterator
    {
    public:
        Iterator(ref<TList<T, Item> > src, ListItem index)
            :  mSource(src), mIndex(index)
        {}

        bool operator !=(const Iterator& it)
        {
            return(!mIndex.Equal(it.mIndex));
        }

        Iterator& operator ++(void)
        {
            mIndex = mIndex->Next();
            return *this;
        }

        ListItem& operator*(void)
        {
            return mIndex;
        }

        ListItem& operator->(void)
        {
            return mIndex;
        }
    private:
        ref<TList<T, Item> > mSource;
        ListItem mIndex;
    };

    /*-------------------------------------------------------------------------
 | ConstIterator:
 | ------------
 | Helper for enumerable class
 ---------------------------------------------------------------------------*/
    class ConstIterator
    {
    public:
        ConstIterator(ref<TList<T, Item> > src, ListItem index)
            :  mSource(src), mIndex(index)
        {}

        bool operator !=(const Iterator& it)
        {
            return(!mIndex.Equal(it.mIndex));
        }

        ConstIterator& operator ++(void)
        {
            mIndex = mIndex->Next();
            return *this;
        }

        ListItem operator*(void)
        {
            return mIndex;
        }
        ListItem operator->(void)
        {
            return mIndex;
        }
    private:
        ref<TList<T, Item> > mSource;
        ListItem mIndex;
    };

    inline Iterator Begin(void)
    {
        return Iterator(this, mFirst);
    }
    inline Iterator End(void)
    {
        return Iterator(this, NullPtr);
    }
};


template<class T, class Item = TListItem<T> >
class List : public ref<TList<T, Item> >
{
    typedef ref<TList<T, Item> > Base;
public:
    typedef ref<Item> ListItem;
public:
    inline List() : Base() {}
    inline List(ref<TList<T, Item> > copy) : Base(copy) {} // for Cast
};
